/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of k3

	k3 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	k3 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with k3.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <types.h>
#include <stdlib/string.h>
#include <stdlib/cmdline.h>

static unsigned long pow(unsigned long x,unsigned long y)
{
	unsigned long mfact=x;
	if(!(y--))
		return 1;
	while(y--)
		x*=mfact;
	return x;
}


unsigned long getnumber(const char *buffer)
{
	size_t str_scan=0;
	size_t number_length=0;
	size_t number=0;
	if(*buffer=='0' && *(buffer+1)=='x') {
		buffer+=2;
		number_length=strlen(buffer);
		for(str_scan=0;str_scan<number_length;str_scan++) {
			if(*(buffer+str_scan)>='0' && *(buffer+str_scan)<='9') {
				number+=(pow(16,number_length-str_scan-1))*(*(buffer+str_scan)-'0');
			}
			else if(*(buffer+str_scan)>='A' && *(buffer+str_scan)<='F') {
				number+=(pow(16,number_length-str_scan-1))*(*(buffer+str_scan)-0x37);
			}
			else if(*(buffer+str_scan)>='a' && *(buffer+str_scan)<='f') {
				number+=(pow(16,number_length-str_scan-1))*(*(buffer+str_scan)-0x57);
			}
		}
	} else {
		number_length=strlen(buffer);
		for(str_scan=0;str_scan<number_length;str_scan++) {
			number=number+(pow(10,number_length-str_scan-1))*(*(buffer+str_scan)-'0');
		}
	}
	return number;
}



/*Following functions do not do any error checking and hence it is recommended that getparamcount should be called
to validate user input.*/

int getstringparameter(const char *buffer,char *ret_string,char separator,size_t ret_sno)
{
	size_t str_count=0,ipcnt=0,len;
	size_t pcnt=0;
	len = strlen(buffer);
	while(str_count<=len)	{
		if(*(buffer+str_count)==separator && *(buffer+str_count+1)!=separator)	{
			pcnt++;
		} else	{
			if(pcnt==ret_sno)	{
				*(ret_string+ipcnt)=*(buffer+str_count);
				ipcnt++;
			}
		}
		str_count++;
	}
	*(ret_string+ipcnt)=0;
	return 0;
}

size_t getstringparameter_offset(const char *buffer, char separator, size_t ret_sno)
{
	size_t str_count=0,ipcnt=0,len;
	size_t pcnt=0;
	len = strlen(buffer);
	while(str_count<=len)	{
		if(*(buffer+str_count)==separator && *(buffer+str_count+1)!=separator)	{
			pcnt++;
		} else	{
			if(pcnt==ret_sno)	{
				return str_count;
			}
		}
		str_count++;
	}
	return 0;
}

/*This function gets the string surrounded by start and end*/
int getstringenv(const char *buffer,char *ret_string,char start,char end, u32 *end_ptr)
{
	size_t i=0,slen,j=0;
	char t=0;
	slen=strlen(buffer);
	while(i < slen)	{
		if(t==0 && *(buffer+i)==start)	{
			t=1;
			i++;
		}
		if(t==1 && *(buffer+i)==end)	{
			t=2;
			break;
		}
		if(t)	{
			*(ret_string+j)=*(buffer+i);
			j++;
		}
		i++;
	}
	*(ret_string+j)=0;
	if(end_ptr)
		(*end_ptr) = i+1;
	if(t==2) {
		return 0;
	} else {
		return -1;
	}
}

int getparamcount(const char *buffer,char separator)
{
	size_t str_count=0,pcnt=0,len;
	len = strlen(buffer);
	while(str_count<=len)	{
		if(*(buffer+str_count)==separator && *(buffer+str_count+1)!=separator)	{
			pcnt++;
		}
		str_count++;
	}
	return pcnt+1;
}

int getparam(const char *buffer,char separator,size_t ret_sno)
{
	char opt[50];
	getstringparameter(buffer,opt,separator,ret_sno);
	return getnumber(opt);
}
